fix(tmux): session env never reached the pane, so script agents ran blind - #279
Merged
Conversation
…lind
Found by running a script-runtime agent from a column for the first time.
argv, cwd and exit-code advancement were already correct — the script got
exactly `--preset high --out cut.mp4`, with no prose prompt appended, and a
deliberately strict argument parser accepted it (`ARGC: 4`). But every
environment variable arrived unset:
PRESET: <unset> THREADS: <unset>
TRIGGER_PROMPT: <unset> WORKING_DIR: <unset>
Session environment was being applied with `Command::env` on the tmux
*client* process. The tmux server is a pre-existing daemon, so `new-session`
only asks it to create a session and the new shell inherits the **server's**
environment, not the client's. Everything set that way was silently dropped.
That is also why the `KAITENCODE_PARENT_*` attribution variables are
additionally inlined on the command line as `KEY=val <cmd>` — that
workaround covered exactly those and nothing else.
Consequences: a script agent's configured `env` was inert while the dossier
displayed it, and script agents received no prompt at all — neither in argv
(correctly, it would break strict parsers) nor in `$TRIGGER_PROMPT`. They
ran context-free. The claim in the previous commit that the prompt rides
`$TRIGGER_PROMPT` was true of the intent and false of the behaviour.
`tmux new-session -e KEY=VAL` sets it server-side and the pane created by
`new-session` inherits it, including values containing spaces and `=`.
Verified against tmux 3.4, which is what ships here. Applied to both session
creation paths — the trigger one and the interactive one, which had the same
bug.
Same run afterwards:
PRESET: fast THREADS: 8
TRIGGER_PROMPT: Render the cut… WORKING_DIR: …/worktrees/kaitencode-…
Also confirms the resolver's script handling from #275 holds in practice:
the column deliberately carried a stale `cli: claude` and `runtime_mode:
managed`, and both were correctly ignored — the run resolved to `terminal`
and executed the agent's own command.
One test-artifact worth recording: deleting a worktree out from under a live
tmux session leaves the pane's cwd on a removed inode, and the next command
fails with `getcwd: cannot access parent directories`. That is the situation
`column_is_terminal` already forces a fresh pane for; it was my reset
sequence, not a product bug.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found by running a script-runtime agent from a column for the first time — the MVP runtime that had never actually executed.
What already worked
argv, cwd and exit-code advancement were correct. The script received exactly
--preset high --out cut.mp4, with no prose prompt appended, and a deliberately strict argument parser accepted it (ARGC: 4). #275's script handling held up: the column carried a stalecli: claudeandruntime_mode: managedon purpose, and both were correctly ignored — the run resolved toterminaland executed the agent's own command.What didn't
Every environment variable arrived unset:
Session environment was applied with
Command::envon the tmux client. The tmux server is a pre-existing daemon, sonew-sessiononly asks it to create a session — the new shell inherits the server's environment, not the client's. Everything set that way was silently dropped.That's also why the
KAITENCODE_PARENT_*attribution variables are additionally inlined on the command line asKEY=val <cmd>: that workaround covered exactly those and nothing else.Consequences: a script agent's configured
envwas inert while the dossier displayed it, and script agents received no prompt at all — not in argv (correctly; it would break strict parsers) and not in$TRIGGER_PROMPT. They ran context-free. My claim in #277 that the prompt rides$TRIGGER_PROMPTwas true of the intent and false of the behaviour.Fix
tmux new-session -e KEY=VALsets it server-side and the pane inherits it, including values with spaces and=. Verified against tmux 3.4. Applied to both session-creation paths — the trigger one and the interactive one, which had the same bug.Same run afterwards:
Pipeline: Todo → Render → Done, exit 0,
mode: terminal.Test-artifact worth recording
Deleting a worktree out from under a live tmux session leaves the pane's cwd on a removed inode, and the next command fails with
getcwd: cannot access parent directories. That's the situationcolumn_is_terminalalready forces a fresh pane for — it was my reset sequence, not a product bug. Noting it because it produced one convincingly wrong-looking run before I spotted it.Checks
cargo clippy -D warnings·cargo test --lib568 (+2) ·tsc·eslint·vitest444.